﻿

using IotContract.Dtos.Clients;
using IotContract.Dtos.Servers;
using IotContract.Enums;
using IotContract.Interfaces.Fmt;
using IotContract.Interfaces;
using IotContract.Interfaces.Process;
using QjServerProcess.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using XT.Common.Services;
using QjServerProcess.Interfaces;
using IotContract.Dtos.Servers.Process;
using IotContract.Dtos.Servers.Pushs;
using XT.Common.Extensions;
using System.Collections.Concurrent;

namespace QjServerProcess.DataProcess;
public class CvDataProcess : IServerProcessHandle
{
    private readonly IServerMainManager _mainProcess;
    private readonly IProcessDataService _processDataService;
    private readonly ILogService _logService;

    public CvDataProcess(IServerMainManager serverMainManager, IProcessDataService processDataService, ILogService logService)
    {
        _mainProcess = serverMainManager;
        _processDataService = processDataService;       
        _logService = logService;
    }
    public string ProcessName { get; set; }= QjServerConst.ProcessName;
    public IotEquipType ProcessType { get; set; } = IotEquipType.CV;

    public event EventHandler<IotEquipWarnDto> WarnEvent;

    /// <summary>
    /// 任务目的地字典
    /// </summary>
    private ConcurrentDictionary<int, int> TaskDestDic = new ConcurrentDictionary<int, int>();

    /// <summary>
    /// 解析数据
    /// </summary>
    /// <returns></returns>
    public async Task<bool> ParsingData()
    {
        try
        {
            // 获取数据
            var equips = await _mainProcess.GetEquips<PushSiemensS7Dto>(new IotContract.Models.Clients.ClientRequestCommand
            {
                RequestType = IotEquipType.CV.ToString(),
                ProtobufType = IotProtobufType.SIEMENS_S7.ToString()
            });
            // 获取扫码枪
            var bcrDic = _processDataService.Bcrs;

            List<PushEquipTag> tags = new List<PushEquipTag>();
            foreach (var equip in equips)
            {
                tags.AddRange(equip.Tags);
            }

            // tags根据TagNum分组,TagNum=UnitNum，TagNum 也就是站台号
            var tagDic = tags.ToLookup(x => x.TagNum).ToDictionary(x => x.Key, y => y.ToList());

            var cvUnitDic = _processDataService.CvUnitTags;

            Parallel.ForEach(tagDic.Keys, x =>
            {
                var tagNum = x.To<int>();
                // 设备号
                var tags = tagDic[x];
                ZdCvUnitDto unitTag = null;
                if (cvUnitDic.ContainsKey(tagNum))
                {
                    unitTag = cvUnitDic[tagNum];
                }
                else
                {
                    unitTag = new ZdCvUnitDto();
                    unitTag.TagNum = tagNum;
                    var equip = equips.FirstOrDefault(x => x.Id == tags.FirstOrDefault()?.EquipInfoId);
                    unitTag.EquipNum = equip.Num;
                    unitTag.EquipId = equip.Id;
                    unitTag.Connection = equip.Connection;
                    unitTag.ProtobufType = equip.ProtobufType;
                    cvUnitDic.TryAdd(tagNum, unitTag);
                }

                // 赋值扫码枪
                //if (bcrDic.ContainsKey(tagNum))
                //{
                //    unitTag.UseBcr = true;
                //    unitTag.Bcrs = bcrDic[tagNum];
                //}

                SetUnitTag(unitTag, tags);



            });

          
        }
        catch(Exception ex)
        {
            Console.WriteLine(ex.Message);
        }

          return true;


    }

    /// <summary>
    /// 设置unit的值
    /// </summary>
    /// <param name="unitTag"></param>
    private void SetUnitTag(ZdCvUnitDto unitTag, List<PushEquipTag> tags)
    {
        unitTag.Tags = tags;
        Parallel.ForEach(tags, x =>
        {
            int.TryParse(x.Value, out int result);
            switch (x.TagProperty)
            {
                case "ERROR":
                    {                      
                        unitTag.Error = result;
                        break;
                    }
                case "MODE":
                    {
                        unitTag.Mode = result;
                        break;
                    }
                case "TRAY":
                    {
                        unitTag.Tray = x.Value;
                        break;
                    }
                case "TASK":
                    {


                        unitTag.Task = result;
                       
                        break;
                    }
              // 高位停准
                case "MOVE_5":
                    {


                        unitTag.MoveHigh = result;
                        break;
                    }
                // 低位停准
                case "MOVE_4":
                    {
                        unitTag.MoveLow = result;
                        break;
                    }
                // 前有货
                case "MOVE_0":
                    {
                        if (result == 1 && !unitTag.IsExistTray)
                        {
                            unitTag.TrayInTime = DateTime.Now;
                        }
                        if (result == 0)
                        {
                            unitTag.TrayInTime = null;
                            unitTag.TrayOnMinutes = 0;
                        }
                        if (unitTag.TrayInTime != null)
                        {
                            unitTag.TrayOnMinutes = Math.Round(DateTime.Now.Subtract(unitTag.TrayInTime.Value).TotalMinutes, 0);
                        }
                        unitTag.IsExistTray = result == 1;
                        break;
                    }
                case "W_TARGET":
                    {
                        unitTag.W_Dest = result;
                        break;
                    }



            }

        });
        // 存在任务号和下发地址，内存记录
        if(unitTag.Task>0 && unitTag.W_Dest > 0)
        {
            if(TaskDestDic.ContainsKey(unitTag.Task))
            {
                TaskDestDic[unitTag.Task]=unitTag.W_Dest;
            }
            else
            {
                TaskDestDic.TryAdd(unitTag.Task, unitTag.W_Dest); 
            }
        }
    }

    public async Task<bool> ProcessData()
    {
        return true;
    }

    public async Task<bool> ProcessOrder()
    {
        return true;
    }

    public async Task<bool> ProcessWarn()
    {
        return true;
    }

    public bool Stop()
    {
        _processDataService.CvUnitTags.Clear();
        return true;
    }
}
